package visiopuce.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import visiopuce.ApplicationContexte;
import visiopuce.HibernateUtil;
import visiopuce.DAO.AnalyseDAO;
import visiopuce.DAO.AnalyseDAOImpl;
import visiopuce.DAO.ChampDAO;
import visiopuce.DAO.ChampDAOImpl;
import visiopuce.DAO.CotationDAO;
import visiopuce.DAO.CotationDAOImpl;
import visiopuce.DAO.HistoriqueDAO;
import visiopuce.DAO.HistoriqueDAOImpl;
import visiopuce.DAO.TypeCotationDAOImpl;
import visiopuce.objets.Analyse;
import visiopuce.objets.Champ;
import visiopuce.objets.Cotation;
import visiopuce.objets.Historique;
import visiopuce.objets.Secteur;
import visiopuce.objets.TypeCotation;
import visiopuce.objets.Utilisateur;

public class AnalyseServiceImpl implements AnalyseService {

	private static final Log log = LogFactory.getLog(AnalyseService.class);

	private AnalyseDAO analyseDAO = AnalyseDAOImpl.getInstance();
	private HistoriqueDAO historiqueDAO = HistoriqueDAOImpl.getInstance();
	private CotationDAO cotationDAO = CotationDAOImpl.getInstance();
	private ChampDAO champDAO = ChampDAOImpl.getInstance();

	/** Constructeur priv� */
	private AnalyseServiceImpl() {
	}

	/** Instance unique non pr�initialis�e */
	private static AnalyseServiceImpl INSTANCE = null;

	/** Point d'acc�s pour l'instance unique du singleton */
	public static AnalyseService getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new AnalyseServiceImpl();
		}
		return INSTANCE;
	}

	public List<Analyse> findAllByidPrelevement(Integer idPrelevement) {
		List<Analyse> analyses = null;

		HibernateUtil.beginTransaction();
		analyses = analyseDAO.findAllByidPrelevement(idPrelevement);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyses;
	}

	public void save(Analyse analyse) {
		HibernateUtil.beginTransaction();
		try {
			ArrayList<Cotation> cotations = new ArrayList<Cotation>();
			if (analyse.getIdAnalyse() == 0) {
				ArrayList<String> listeCotation = new ArrayList<String>();
				if (analyse.getTypeAnalyse().getLibelle().contains("Puce")) {
					listeCotation = ApplicationContexte.cotationPuce;
					// // foeto
					// if
					// (analyse.getPrelevement().getIndication().getCategorie()
					// == 3) {
					// listeCotation.add("AN923");
					// } else {
					// listeCotation.add("AQ901");
					// listeCotation.add("AQ048");
					// if
					// (analyse.getPrelevement().getSecteur().getLibelle().contains("Puce prénatale"))
					// {
					// listeCotation.add("AN018");
					// listeCotation.add("AN014");
					// }
					// }
				}
				if (analyse.getTypeAnalyse().getLibelle().contains("caryotype")) {
					if (analyse.getPrelevement().getSecteur().getLibelle().equals(ApplicationContexte.SECTEUR_FOETO)) {
						listeCotation.add("A0902");
					}
					if (analyse.getPrelevement().getSecteur().getLibelle().equals(ApplicationContexte.SECTEUR_POSTNATAL)) {
						listeCotation.add("A0901");
						listeCotation.add("AB046");
					}
					if (analyse.getPrelevement().getSecteur().getLibelle().equals(ApplicationContexte.SECTEUR_PRENATAL)) {
						listeCotation.add("A0041");
						if (analyse.getPrelevement().getTypePrelevement().getLibelle().contains("chorial")) {
							listeCotation.add("AQ012");
						}
					}
				}
				if (analyse.getTypeAnalyse().getLibelle().contains("aneuvysion")) {
					listeCotation.add("A0905");
				}
				if (analyse.getTypeAnalyse().getLibelle().contains("caryotype en examen direct")) {
					listeCotation.add("AB001");
				}
				for (String cotation : listeCotation) {
					List<TypeCotation> tc = TypeCotationDAOImpl.getInstance().getTypeCotation(cotation);
					Cotation c = new Cotation();
					c.setDate(new Date());
					c.setTypeCotation(tc.get(0));
					cotations.add(c);
				}

			}
			analyseDAO.save(analyse);

			ArrayList<Champ> champs = analyse.getChamps();
			champDAO.deleteAllByidObjet("Ana-" + analyse.getIdAnalyse());
			Historique h4 = new Historique();
			h4.setDate(new Date());
			h4.setRequete("Suppression des champs de l'objet" + "Ana-" + analyse.getIdAnalyse());
			h4.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h4);
			if (champs != null) {
				for (Champ champ : champs) {

					Champ champOld = champDAO.getChampByTypeAndIdObjet(champ.getType(), champ.getIdObjet());
					if (champOld != null) {
						champOld.setValeur(champ.getValeur());
						champ = champOld;
					} else {
						champ.setIdObjet("Ana-" + analyse.getIdAnalyse());
					}
					champDAO.save(champ);
					Historique h2 = new Historique();
					h2.setDate(new Date());
					h2.setRequete("Enregistrement " + champ.toString());
					h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
					historiqueDAO.save(h2);
				}
			}

			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("save " + analyse.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			for (Cotation cotation : cotations) {
				cotation.setAnalyse(analyse);
				cotationDAO.save(cotation);

			}
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
			HibernateUtil.closeSession();
		}
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
	}

	public Analyse getAnalyseByIdAnalyse(int idAnalyse) {
		Analyse analyse = null;

		HibernateUtil.beginTransaction();
		analyse = analyseDAO.findByID(Analyse.class, idAnalyse);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyse;
	}

	public String[] getUFExecs() {

		HibernateUtil.beginTransaction();
		List luFExec = analyseDAO.getAllUFExec();
		HibernateUtil.commitTransaction();
		Object[] ouFExec = (Object[]) luFExec.toArray();
		String[] uFExec = new String[ouFExec.length];
		for (int i = 0; i < ouFExec.length; i++) {
			if (ouFExec[i] != null) {
				uFExec[i] = ((Integer) ouFExec[i]).toString();
			}
		}
		return uFExec;
	}

	public Analyse refresh(Analyse analyse) {
		if (analyse.getIdAnalyse() != 0) {
			HibernateUtil.beginTransaction();
			HibernateUtil.getSession().refresh(analyse);
			HibernateUtil.closeSession();
		}
		return analyse;
	}

	@Override
	public boolean isUrgent(Integer idAnalyse) {
		boolean isUrgent = false;
		if (idAnalyse != 0) {
			HibernateUtil.beginTransaction();
			isUrgent = analyseDAO.isUrgent(idAnalyse);
			HibernateUtil.closeSession();
		}
		return isUrgent;
	}

	@Override
	public Secteur getSecteurByIdAnalyse(Integer idAnalyse) {
		Secteur secteur = null;
		HibernateUtil.beginTransaction();
		secteur = analyseDAO.getSecteurByIdAnalyse(idAnalyse);
		HibernateUtil.closeSession();
		return secteur;
	}

	@Override
	public Analyse getAnalyseByTypeAndNumeroPrelevement(int idType, String numeroDossier) {
		Analyse analyse = null;

		HibernateUtil.beginTransaction();
		analyse = analyseDAO.getAnalyseByTypeAndNumeroPrelevement(idType, numeroDossier);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyse;
	}

	@Override
	public Analyse getAnalyseByPersonneTypeAnalyse(Integer idPersonne, int typeAnalyse) {
		Analyse analyse = null;

		HibernateUtil.beginTransaction();
		analyse = analyseDAO.getAnalyseByPersonneTypeAnalyse(idPersonne, typeAnalyse);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyse;
	}

	// @Override
	// public HashMap<String, List<Analyse>> findAllByUtilisateur(Utilisateur
	// user) {
	// HashMap<String, List<Analyse>> analyses = new HashMap<String,
	// List<Analyse>>();
	// HibernateUtil.beginTransaction();
	// String travail = user.getTravail();
	// if (travail != null) {
	// String[] secteurs = travail.split(";");
	// for (String secteur : secteurs) {
	// String[] secteurAnalyse = secteur.split("-");
	// if (user.getBiologiste() != null) {
	// analyses.put(secteur,
	// analyseDAO.findAllASigner(Integer.parseInt(secteurAnalyse[0]),
	// Integer.parseInt(secteurAnalyse[1])));
	// } else {
	// analyses.put(secteur,
	// analyseDAO.findAllATechniquer(Integer.parseInt(secteurAnalyse[0]),
	// Integer.parseInt(secteurAnalyse[1])));
	// }
	// }
	//
	// HibernateUtil.commitTransaction();
	// }
	// HibernateUtil.closeSession();
	// return analyses;
	// }

	@Override
	public List<Analyse> getAnalysePuceReunion() {
		List<Analyse> analyses = new ArrayList<Analyse>();
		HibernateUtil.beginTransaction();
		analyses = analyseDAO.getAnalysePuceReunion();
		HibernateUtil.commitTransaction();

		HibernateUtil.closeSession();
		return analyses;
	}

	@Override
	public List<Analyse> getListeADN(int annee) {
		List<Analyse> analyses = null;

		HibernateUtil.beginTransaction();
		analyses = analyseDAO.getListeADN(annee);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyses;
	}

	@Override
	public void delete(Analyse analyse) {
		HibernateUtil.beginTransaction();
		try {
			List<Cotation> cotations = CotationDAOImpl.getInstance().getCotationByidAnalyse(analyse.getIdAnalyse());

			for (Cotation cotation : cotations) {
				Historique h2 = new Historique();
				h2.setDate(new Date());
				h2.setRequete("Suppression " + cotation.toString());
				h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
				historiqueDAO.save(h2);
				CotationDAOImpl.getInstance().delete(cotation);
			}
			Historique h3 = new Historique();
			h3.setDate(new Date());
			h3.setRequete("Suppression " + analyse.toString());
			h3.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h3);

			analyseDAO.delete(analyse);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	public List<Analyse> findAllByidPersonne(Integer idPersonne) {
		List<Analyse> analyses = null;

		HibernateUtil.beginTransaction();
		analyses = analyseDAO.findAllByidPersonne(idPersonne);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyses;
	}

	@Override
	public List<Analyse> getListeTravail(String travail, String analyse) {
		List<Analyse> analyses = null;

		HibernateUtil.beginTransaction();
		analyses = analyseDAO.getListeTravail(travail, analyse);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return analyses;
	}
}